package com.vipbbo.spring.config;


import com.vipbbo.spring.transaction.AccountByAnnotationService;
import com.vipbbo.spring.transaction.AccountByAnnotationServiceImpl;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.net.ProtocolException;

@ComponentScan(basePackages = {"com.vipbbo"})
@Configuration
//开启基于注解的声明式事务
@EnableTransactionManagement
public class SpringConfig {


	/**
	 * 注解数据源
	 * @return
	 * @throws ProtocolException
	 */
	@Bean
	public DataSource dataSource() throws ProtocolException {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
		dataSource.setUsername("root");
		dataSource.setPassword("root");
		dataSource.setUrl("jdbc:mysql://192.168.1.100:3306/spring_aop?" +
				"useSSL=false&useUnicode=true&characterEncoding=UTF-8");
		return dataSource;
	}

	/**
	 * 注册JdbcTemplate
	 * @return
	 * @throws ProtocolException
	 */
	@Bean
	public JdbcTemplate jdbcTemplate() throws ProtocolException{
		// 两种方式获取DataSOurce
		//1. 直接在方法上放置参数 public JdbcTemplate jdbcTemplate(DataSource dataSource)
		// 默认会去容器去取
		// 2. 如下： 调用上面的方法
		//spring对@Configuration类有特殊处理，注册组件的方法多次调用只是在IOC容器中找组件
		return new JdbcTemplate(dataSource());
	}

	/**
	 * 注册事务管理器
	 * @return
	 * @throws ProtocolException
	 */
	@Bean
	public PlatformTransactionManager transactionManager() throws ProtocolException{
		//需要传入dataSource
		return new DataSourceTransactionManager(dataSource());
	}

	/**
	 * 注册业务bean  也可通过注解@Service在实现类AccountByAnnotationServiceImpl 实现
	 * @return
	 */
	@Bean
	public AccountByAnnotationService accountByAnnotationService(){
		return new AccountByAnnotationServiceImpl();
	}
}
